package com.sq.partner.manager.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.log4j.Logger;

public class SQLReader implements Serializable {
    private static Logger logger = LogUtil.getLog(SQLReader.class);
	private static SQLReader INSTANCE = null;
	// SQL 文件名字
	private static String fn = "sql.txt";
	// SQL语句名称标识
	private static String namePrefix = "--*";
	// SQL文件读取环境
	private static boolean webEnvironment = true;
	// 输出SQL
	private static boolean isOutputSQL = false;
	// 读取注释
	private static boolean isReadRemark = false;
	// 注释标识
	private static String remarkPrefix = "--";

    // 注释标识
    private static String jarPrefix = "JxLife";

	private static Hashtable<String, String> sqlList;

    static{
        INSTANCE = new SQLReader();
    }

	private SQLReader() {
		initialize();
        logger.info("Finish reading sql statement file!");
	}


    private void initialize() {
        logger.info("Start reading sql statement file...");
        sqlList = new Hashtable<String, String>();
        if (this.webEnvironment)
            webRead();
        else{
            javaRead();
        }
    }

    private void webRead() {
        try{
            webSrcRead();
        }catch (Exception e){
            logger.error(e);
        }

        try{
            webJarRead();
        }catch (IOException e){
            logger.error(e);
        }
    }

    /**
     * 遍例class中的*.sql文件
     */
	private void webSrcRead() throws IOException {
		String sql_file=getWebINFPath()+"/classes";
        File fLib = new File(sql_file);
        getAllSql(fLib);

	}

    private void getAllSql(File file) throws IOException {
        if(file.isDirectory()){
            File[] fa = file.listFiles();
            for(File f : fa){
                getAllSql(f);
            }
        }else{
            String name = file.getName();
            if(name.endsWith(".sql"));
            BufferedReader br = new BufferedReader(new FileReader(file));
            read(br);
            br.close();
        }

    }

    /**
     * 获取lib中的JxLife开头的jar包里面的*.sql文件，开发时sql文件要放到resource包里，不然可能打的jar包中不包括sql文件
     * @throws IOException
     */
    private void webJarRead() throws IOException{

        String dirLib = getWebINFPath() +"/lib";
        File fLib = new File(dirLib);
        File[] fa = fLib.listFiles();
        for(File f : fa){
            String name = f.getName();
            if(name.startsWith(jarPrefix) && name.endsWith("jar")){
                JarFile jarFile = new JarFile(f);
                Enumeration<JarEntry> entrys = jarFile.entries();
                while (entrys.hasMoreElements()) {
                    JarEntry jarEntry = entrys.nextElement();
                    String entryName = jarEntry.getName();
                    if (entryName.endsWith(".sql")) {
                        BufferedReader br =
                                new BufferedReader( new InputStreamReader(this.getClass().getResourceAsStream("/"+entryName)));
                        read(br);
                        br.close();

                    }
                }
            }

        }

    }

    private String getWebINFPath(){
        String classPath=this.getClass().getResource("").getPath();
        String path = classPath.substring(0,classPath.indexOf("/WEB-INF/")+8).replaceAll("^file:","");
        logger.debug("WEB-INF path"+ path);
        return path;
    }

	private void javaRead() {
		FileReader fileReader = null;
		try {
			fileReader = new FileReader(fn);
		} catch (FileNotFoundException ex) {
			logger.fatal(ex);
			return;
		}
		BufferedReader reader = new BufferedReader(fileReader);
		read(reader);
	}

	private void read(BufferedReader reader) {
		int beginIndex = namePrefix.length();
		String str = null;
		String name = null;
		String sqlStatement = null;
		try {
			while ((str = reader.readLine()) != null) {
				if (str.trim().startsWith(namePrefix)) {
					if (name != null && sqlStatement != null) {
						this.setSQL(name, sqlStatement);
					}
					name = str.trim().substring(beginIndex);
					sqlStatement = null;
				} else {
					if (str.trim().length() > 0) {
						if (!isReadRemark
								&& str.trim().startsWith(remarkPrefix)) {
							continue;
						}
						if (sqlStatement == null) {
							sqlStatement = str;
						} else {
							sqlStatement += "\n" + str;
						}
					}
				}
			}
		} catch (IOException ex) {
			logger.fatal(ex);
		}
		if (name != null && sqlStatement != null) {
			this.setSQL(name, sqlStatement);
		}
	}

	private void setSQL(String sqlName, String sqlStatement) {
		this.sqlList.put(sqlName, sqlStatement);
	}

	public static String getSQL(String sqlName) {
		String sql = (String) INSTANCE.sqlList.get(sqlName);
		if (isOutputSQL) {
            logger.info("execute SQL " + sqlName);
		} else {
            logger.debug("execute SQL " + sqlName);
            //logger.logDebug(sql);
		}
		return sql;
	}
}